import sys
import argparse
from lexer import tokenize
from parser import parse
from codegen import generate_llvm_ir

def compile_to_llvm(source_code, output_file=None):
    """将源代码编译为LLVM IR"""
    try:
        # 1. 词法分析
        print("正在进行词法分析...")
        tokens = tokenize(source_code)
        print(f"词法分析完成，共识别出 {len(tokens)} 个标记")
        
        # 2. 语法分析
        print("正在进行语法分析...")
        # Ply的yacc模块需要完整的源代码字符串进行分析
        ast = parse(source_code)
        if not ast:
            raise Exception("语法分析失败")
        print("语法分析完成，成功构建AST")
        
        # 添加更多调试信息来检查AST结构
        print(f"AST类型: {type(ast)}")
        if hasattr(ast, 'node_type'):
            print(f"AST节点类型: {ast.node_type}")
        else:
            print("AST没有node_type属性")
        
        # 检查AST的结构
        if hasattr(ast, 'node_type') and ast.node_type == 'Program' and hasattr(ast, 'children'):
            print(f"AST包含 {len(ast.children)} 个语句")
            # 保存函数定义的数量
            func_count = 0
            for i, child in enumerate(ast.children):
                node_type = getattr(child, 'node_type', 'unknown')
                if node_type == 'Function':
                    func_count += 1
                    func_name = child.value.get('name', 'unknown') if hasattr(child, 'value') else 'unknown'
                    print(f"  - 语句{i+1}: {node_type} {func_name}")
                    # 检查函数体结构
                    if hasattr(child, 'children') and len(child.children) > 1:
                        body = child.children[1]
                        print(f"    - 函数体类型: {getattr(body, 'node_type', 'unknown')}")
                        if hasattr(body, 'children'):
                            print(f"    - 函数体内语句数: {len(body.children)}")
                elif node_type == 'VarDeclaration' and hasattr(child, 'value'):
                    var_name = child.value.get('name', 'unknown')
                    print(f"  - 语句{i+1}: {node_type} {var_name}")
                else:
                    print(f"  - 语句{i+1}: {node_type}")
            print(f"总共找到 {func_count} 个函数定义")
        else:
            print("AST不是Program类型或没有children属性")
            # 尝试直接打印AST的所有属性
            print(f"AST的所有属性: {dir(ast)}")
        
        # 3. 代码生成
        print("正在生成LLVM IR...")
        llvm_module = generate_llvm_ir(ast)
        llvm_ir = str(llvm_module)
        print("LLVM IR生成完成")
        
        # 输出结果
        if output_file:
            with open(output_file, 'w', encoding='utf-8') as f:
                f.write(llvm_ir)
            print(f"LLVM IR已保存到: {output_file}")
        else:
            print("\n===== LLVM IR =====")
            print(llvm_ir)
        
        return llvm_ir
        
    except Exception as e:
        import traceback
        print(f"编译错误: {e}")
        print("错误堆栈:")
        traceback.print_exc()
        raise

def main():
    """主函数"""
    parser = argparse.ArgumentParser(description='简单编译器 - 将源代码编译为LLVM IR')
    parser.add_argument('input_file', help='输入的源代码文件路径')
    parser.add_argument('-o', '--output', help='输出的LLVM IR文件路径')
    
    args = parser.parse_args()
    
    # 读取输入文件
    try:
        with open(args.input_file, 'r', encoding='utf-8') as f:
            source_code = f.read()
        
        print(f"正在编译文件: {args.input_file}")
        compile_to_llvm(source_code, args.output)
        
    except FileNotFoundError:
        print(f"错误: 找不到文件 '{args.input_file}'")
        sys.exit(1)
    except Exception as e:
        print(f"错误: {e}")
        sys.exit(1)

if __name__ == '__main__':
    main()